#!/usr/bin/env python
# Author: Chris Moyer
VERSION = 0.1

import os
import sys
sys.path.append(".")
sys.path.append("lib")

from datetime import datetime, timedelta


def choice_input(cls, default=None, title=None, filters=[]):
    """
    Choice input
    """
    if title == None:
        title = "Please choose a %s" % cls.__name__.lower()
    print title
    objects = []
    query = cls.find()
    for filter in filters:
        query.filter(filter[0], filter[1])
    for n, obj in enumerate(query):
        print "%s: %s" % (n, obj)
        objects.append(obj)
    choice = raw_input("%s: " % cls.__name__.lower())
    try:
        choice = objects[int(choice)]
    except:
        choice = default
    return choice

def ticket_report(query):
    """
    Base report generator for ticket
    based reports
    """
    from resources.project import Project
    from resources.release import Release
    from resources.ticket import Ticket
    from resources.client import Client
    project = choice_input(Project)
    query.filter("project =", project)

    release = choice_input(Release, title="Please choose a release (optional)", filters=[ ["project = ", project] ])
    if release:
        query.filter("release =", release)

    print "Please choose a start date (optional)"
    start_date = raw_input("start_date (mm/dd/yy): ").strip()
    if start_date:
        start_date = datetime.strptime(start_date, "%m/%d/%y")
        query.filter("date_finished >", start_date)

    print "Please choose an end date (optional)"
    end_date = raw_input("end_date (mm/dd/yy): ").strip()
    if end_date:
        end_date = datetime.strptime(end_date, "%m/%d/%y")
        query.filter("date_finished <", end_date)
    else:
        end_date = datetime.now()

    
    # Prompt for rates
    print "Please specify hourly rates:"
    rates = {}
    for rate in Ticket.find_property("rate").choices:
        rates[rate] = int(raw_input("%s: " % rate))

    # Prompt for Contact info
    client = choice_input(Client, title="Please choose the client to bill:")

    tickets = []
    total_hours = 0
    total_cost = 0
    total_estimated_hours = 0
    total_estimated_cost = 0
    for t in query:
        total_hours += t.hours
        total_cost += (t.hours * rates[t.rate])
        total_estimated_hours += t.estimated_hours
        total_estimated_cost += (t.estimated_hours * rates[t.rate])
        tickets.append(t)

    return {"project": project, 
                "tickets": tickets, 
                "total_hours": total_hours, 
                "total_cost": total_cost, 
                "total_estimated_hours": total_estimated_hours,
                "total_estimated_cost": total_estimated_cost,
                "rates": rates,
                "client": client,
                "date": datetime.now(),
                "date_due": datetime.now() + timedelta(days=30),
                "start_date": start_date,
                "end_date": end_date,
                "release": release,
                }

def comment_report(query):
    """
    Base for comment reports
    """
    total_hours = 0
    total_cost = 0
    comments = []
    for comment in query:
        total_hours += comment.hours
        comments.append(comment)
    vals = {}
    vals['project'] = project
    vals['comments'] = comments
    vals['total_hours'] = total_hours
    return vals

def work_report():
    from marajo.appengine.api.users import User
    from resources.comment import Comment
    query = Comment.find()
    user = choice_input(User)
    query.filter("user =", user)
    return comment_report(query)

def invoice_report():
    from resources.ticket import Ticket
    query = Ticket.find()
    query.filter("status =", "closed")
    return ticket_report(query)

def estimate_report():
    from resources.ticket import Ticket
    query = Ticket.find()
    query.filter("status =", "open")
    return ticket_report(query)

report_types = {
    "I":  {
                "name": "Invoice", 
                "template": "invoice.tmpl", 
                "generator": invoice_report
            },
    "E":  {
                "name": "Estimate",
                "template": "estimate.tmpl",
                "generator": estimate_report
            },
    "W":  {
                "name": "Work Report",
                "template": "work_report.tmpl",
                "generator": work_report,
            }
}

if __name__ == "__main__":
    from optparse import OptionParser
    parser = OptionParser(version = "%prog version 1.0")
    parser.add_option("-e", "--environment", help="Environment", dest="env", default="prod")
    (options, args) = parser.parse_args()

    import marajo
    marajo_dir = os.path.dirname(os.path.dirname( os.path.realpath( __file__ ) ))
    marajo.set_env(marajo_dir, options.env)

    from marajo.appengine.ext.webapp import template
    print "Please choose a Report Type:"
    for k in report_types:
        print "%s: %s" % (k, report_types[k]['name'])
    report_type = report_types[raw_input("type: ").upper()]

    vals = report_type['generator']()
    out_f_name = raw_input("output file [report.html]: ").strip()
    if not out_f_name:
        out_f_name = "report.html"
    f = open(out_f_name, "w")
    f.write(template.render(report_type['template'],
                vals,
                template_dirs=["templates/reports"]
                ))
    f.close()

